package com.lang.ref.reference;

import java.lang.ref.*;
import java.util.LinkedList;

/**
 * 《Java编程思想》 上面的例子
 * @Description
 * @Author away
 * @Version V1.0.0
 * @Since 1.0
 * @Date 2019/3/13
 */
public class References {

    private static ReferenceQueue<VeryBig> rq = new ReferenceQueue<VeryBig>();
    public static void checkQueue(){
        Reference<? extends VeryBig> inq = rq.poll();
        if(inq!=null){
            System.out.println("In queue:"+inq.getClass().getSimpleName());
        }
    }

    public static void main(String[] args) {
        int size = 10;
        /*
         * SoftReference:在内存不足时才会回收这样软引用对象
         * */
        LinkedList<SoftReference<VeryBig>> sa = new  LinkedList<SoftReference<VeryBig>>();
        for(int i=0;i<size;i++){
            sa.add(new SoftReference(new VeryBig("Soft "+i),rq));
            System.out.println("Just created: "+sa.getLast().get());
            checkQueue();//一直为空
        }
        /*
         * WeakReference:在GC发现只具有弱引用的对象会立即对其会回收
         * */
        LinkedList<WeakReference<VeryBig>> wa = new  LinkedList<WeakReference<VeryBig>>();
        for(int i=0;i<size;i++){
            wa.add(new WeakReference(new VeryBig("Weak "+i),rq));
            System.out.println("Just created: "+wa.getLast().get());
            checkQueue();
        }

        SoftReference<VeryBig> sf = new SoftReference<VeryBig>(new VeryBig("Soft "));
        WeakReference<VeryBig> wf = new WeakReference<VeryBig>(new VeryBig("Weak"));

        System.gc();//显示的进行垃圾回收，什么时候执行就由JVM决定
        // 如果 JVM 先 GC 回收了 WeakReference 里面的对象，那么 ReferenceQueue 里面的值是存在的
        //如果 JVM 先 GC 线程最后在被调用，那么 ReferenceQueue 里面的 ENQUEUED 队列为空。

        LinkedList<PhantomReference<VeryBig>> pa = new  LinkedList<PhantomReference<VeryBig>>();
        for(int i=0;i<size;i++){
            pa.add(new PhantomReference(new VeryBig("Phantom "+i),rq));
            System.out.println("Just created: "+pa.getLast());
            checkQueue();
        }
    }

}

class VeryBig{
    private static final int SIZE = 10000;
    private long[] la = new long[SIZE];
    private String ident;
    public VeryBig(String id){
        ident = id;
    }
    @Override
    public String toString(){
        return ident;
    }


    @Override
    protected void finalize(){
        System.out.println("Finalizing "+ ident);
    }

}
/* output
Just created: Soft 0
Just created: Soft 1
Just created: Soft 2
Just created: Soft 3
Just created: Soft 4
Just created: Soft 5
Just created: Soft 6
Just created: Soft 7
Just created: Soft 8
Just created: Soft 9
Just created: Weak 0
Just created: Weak 1
Just created: Weak 2
Just created: Weak 3
Just created: Weak 4
Just created: Weak 5
Just created: Weak 6
Just created: Weak 7
Just created: Weak 8
Just created: Weak 9
Finalizing Weak 8
Finalizing Weak
Finalizing Soft
Finalizing Weak 9
Finalizing Weak 7
Finalizing Weak 6
Finalizing Weak 5
Finalizing Weak 4
Finalizing Weak 3
Finalizing Weak 2
Finalizing Weak 1
Finalizing Weak 0
Just created: java.lang.ref.PhantomReference@60e53b93
In queue:WeakReference
Just created: java.lang.ref.PhantomReference@5e2de80c
In queue:WeakReference
Just created: java.lang.ref.PhantomReference@1d44bcfa
In queue:WeakReference
Just created: java.lang.ref.PhantomReference@266474c2
In queue:WeakReference
Just created: java.lang.ref.PhantomReference@6f94fa3e
In queue:WeakReference
Just created: java.lang.ref.PhantomReference@5e481248
In queue:WeakReference
Just created: java.lang.ref.PhantomReference@66d3c617
In queue:WeakReference
Just created: java.lang.ref.PhantomReference@63947c6b
In queue:WeakReference
Just created: java.lang.ref.PhantomReference@2b193f2d
In queue:WeakReference
Just created: java.lang.ref.PhantomReference@355da254
In queue:WeakReference
 */

